/* Copyright (C) 2008  Romolo Camplani, Marco Fortunato, Marco Marelli, Guido Rota, Fabio A. Schreiber et al.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.dei.perla.rockfall.gui;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyVetoException;
import java.util.ArrayList;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.dei.perla.rockfall.RockfallManager;
import org.dei.perla.sys.query.llqruntime.datastructures.Record;
import org.dei.perla.utils.pipe.Pipe;

public class MainWindow extends JFrame implements ActionListener {

	private static final long serialVersionUID = 7284057328471308072L;
	
	// Graphic elements
	private JDesktopPane desktopPane;
	private JMenu windowMenu;
	private QueryWindow queryWindow;
	
	private ArrayList<DataViewer> dataViewerList;
	
	public MainWindow(RockfallManager manager) {
		
		super("Rockfall Monitor");
		
		// Setting the Look and Feel
		try {
			
			UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
			
			// Questo da' problemi, i JInternalFrame non occupano tutto lo spazio disponibile
			// (forse per l'ombra che proiettano???)
			//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			
		} catch (InstantiationException e) {
			e.printStackTrace();
			
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
			
		}
		
		// Setup the graphics
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setBounds(0, 0, (int)screenSize.getWidth(), (int)screenSize.getHeight());
		desktopPane = new JDesktopPane();
		add(desktopPane);
		setJMenuBar(createMenuBar());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JFrame.setDefaultLookAndFeelDecorated(true);
		
		if (manager != null) {
			queryWindow = new QueryWindow(manager);
			queryWindow.setVisible(true);
			desktopPane.add(queryWindow);
		}
		
		// Setup control datastructures
		dataViewerList = new ArrayList<DataViewer>();
	}
	
	private JMenuBar createMenuBar() {
		
		JMenuBar menuBar = new JMenuBar();
		JMenuItem menuItem;
		
		// Create the File menu
		windowMenu = new JMenu("File");
		windowMenu.setMnemonic(KeyEvent.VK_F);
		menuBar.add(windowMenu);
		menuItem = new JMenuItem("Exit");
		menuItem.setActionCommand("exit");
		menuItem.addActionListener(this);
		windowMenu.add(menuItem);
		
		// Create the Window menu
		windowMenu = new JMenu("Window");
		windowMenu.setMnemonic(KeyEvent.VK_W);
		menuBar.add(windowMenu);
		// Fit vertically JMenuItem
		menuItem = new JMenuItem("Fit Vertically");
		menuItem.addActionListener(this);
		menuItem.setActionCommand("fit");
		menuItem.setEnabled(false);
		windowMenu.add(menuItem);
		
		return menuBar;
	}
	
	private void redrawWindowMenu() {
		
		JMenuItem menuItem;
		
		windowMenu.removeAll();
		
		// Insert optional DataViewer entries
		for (int i = 0; i < dataViewerList.size(); i++) {
			menuItem = new JMenuItem("DataViewer " + i);
			menuItem.setActionCommand(new Integer(i).toString());
			menuItem.addActionListener(this);
			windowMenu.add(menuItem);
		}
		
		// Insert another nice separator
		windowMenu.addSeparator();
		
		menuItem = new JMenuItem("Fit vertically");
		menuItem.addActionListener(this);
		menuItem.setActionCommand("fit");
		windowMenu.add(menuItem);
		
		// Insert another nice separator
		windowMenu.addSeparator();
		
		// Insert an entry for the QueryWindow
		menuItem = new JMenuItem("Query window");
		menuItem.setActionCommand("query");
		menuItem.addActionListener(this);
		windowMenu.add(menuItem);
	}
	
	private void fitWindows() {
		
		if (dataViewerList.size() != 0) {
			int internalFrameHeight = desktopPane.getHeight() / dataViewerList.size();
			int dataViewerPosition = 0;
			
			for (DataViewer d : dataViewerList) {
				d.setBounds(0, dataViewerPosition, desktopPane.getWidth(), internalFrameHeight);
				d.toFront();
				dataViewerPosition += internalFrameHeight;
			}
		}
	}
	
	public void showGui() {
		
		setVisible(true);
		fitWindows();
	}
	
	public void addDevice(String deviceName, Pipe<Record> recordPipe) {

		DataViewer dataViewer = new DataViewer(deviceName, recordPipe);
		desktopPane.add(dataViewer);
		dataViewerList.add(dataViewer);
		dataViewer.setVisible(true);
		redrawWindowMenu();
	}
	
	public void actionPerformed(ActionEvent event) {

		if (event.getActionCommand().equals("exit")) {
			
			System.exit(0);
			
		} else if (event.getActionCommand().equals("fit")) {
			
			fitWindows();
			
		} else if (event.getActionCommand().equals("query")) {
			
			queryWindow.toFront();
			
		} else {
			
			try {
				Integer windowNumber = new Integer(event.getActionCommand());
				
				if (windowNumber < dataViewerList.size()) {
					
					DataViewer viewer = dataViewerList.get(windowNumber);
					try {
						viewer.setIcon(false);
					} catch (PropertyVetoException e) {}
					viewer.toFront();
				}
			} catch (NumberFormatException e) {}
		}
	}
}
